David Leitão [2019223148]
Rodrigo Machado [2019218299]
Rui Costa [2019224237]
# Notebook setup
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from report import *
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
plt.rcParams['figure.figsize'] = [5, 5]
barn = np.array(Image.open("imagens/barn_mountains.bmp"))
peppers = np.array(Image.open("imagens/peppers.bmp"))
logo = np.array(Image.open("imagens/logo.bmp"))
path = "ex1/barn_mountains"
tmp = np.array(Image.open(f"{path}/high.jpg"))
plt.title("barn_mountains - High (qf=75)")
viewImage(tmp)
Quando vista sem qualquer nível de ampliação, não existem grandes alterações visíveis. No entanto, podemos observar alguns artefactos nos contornos das figuras nas imagens.
tmp = np.array(Image.open(f"{path}/medium.jpg"))
plt.title("barn_mountains - Medium (qf=50)")
viewImage(tmp)
Já são observáveis vários artefactos, maioritariamente nos contornos. Podemos observar também nas sombras do celeiro e na base da montanha. Com alguma ampliação, podemos observar a divisão em píxeis.
tmp = np.array(Image.open(f"{path}/low.jpg"))
plt.title("barn_mountains - Low (qf=25)")
viewImage(tmp)
Observam-se artefactos por toda a imagem. Podemos ver também no céu uma divisão clara em píxeis, que se torna ainda mais visível quanto mais se amplie a imagem.
path = "ex1/peppers"
tmp = np.array(Image.open(f"{path}/high.jpg"))
plt.title("peppers - High (qf=75)")
viewImage(tmp)
A imagem apresenta uma espécie de efeito granular e um brilho menos intenso. Podemos observar com bastante ampliação alguns artefactos nas cortinas.
tmp = np.array(Image.open(f"{path}/medium.jpg"))
plt.title("peppers - Medium (qf=50)")
viewImage(tmp)
Já podemos observar na cortina uma maior quantidade de artefactos, tal como nos contornos das várias figuras. À semelhança da primeira imagem, com alguma ampliação já podemos observar uma divisão em píxeis nas cortinas.
tmp = np.array(Image.open(f"{path}/low.jpg"))
plt.title("peppers - Low (qf=25)")
viewImage(tmp)
A imagem inteira apresenta artefactos visíveis por toda a imagem, especialmente por toda a cortina. A divisão em píxeis torna-se bastante evidente nos objetos vermelhos e nas zonas com reflexos de luz.
path = "ex1/logo"
tmp = np.array(Image.open(f"{path}/high.jpg"))
plt.title("logo - High (qf=75)")
viewImage(tmp)
A imagem inteira apresenta artefactos visíveis por toda a imagem, especialmente por toda a cortina. A divisão em píxeis torna-se bastante evidente nos objetos vermelhos e nas zonas com reflexos de luz.
tmp = np.array(Image.open(f"{path}/medium.jpg"))
plt.title("logo - Medium (qf=50)")
viewImage(tmp)
Na parte vermelha do logo podemos observar artefactos na circunferência sem qualquer ampliação, tal como no fundo branco junto dos contornos. Aplicando alguma ampliação já conseguimos ver o mesmo no contorno da parte azul e podemos verificar também divisões em píxeis nas zonas de mudança de cor.
tmp = np.array(Image.open(f"{path}/low.jpg"))
plt.title("logo - Low (qf=25)")
viewImage(tmp)
Observam-se artefactos na parte colorida e no fundo branco, continuando a ser mais visível nos contornos do que no preenchimento. A pixelização nas zonas de mudança de cor torna se ainda mais percetível com uma menor ampliação do que na qualidade média. Podemos ainda observar alguma pixelização na zona de preênchimento da parte vermelha.
# Matplotlib figure sizing
plt.rcParams['figure.figsize'] = [9, 9]
O modelo RBG é um modelo de cor que, com o conhecimento limitado na altura da sua conceção, tenta simular os cones presentes no olho humano, representando as imagens com 3 canais: Vermelho, Verde, e Vermelho.
No entanto, como todos os canais contêm informação de luminância e cor, o modelo RGB apresenta uma elevada redundância no sinal.
O modelo de cor YCbCr extrai a luminância dos 3 canais de RGB para um único canal, $Y$, e toma em conta a sensibilidade do olho humano ao fazê-lo. Como o olho é mais sensível ao verde e vermelho, esta componente usa menos informação do canal azul. $$Y = 0.3R + 0.6G + 0.1B$$
O canal $Y$ é uma representação acromática da imagem original. Este canal não é comprimido pelo codec de JPEG, pois o olho humano é sensível à informação contida na porção acromática da imagem, como se pode verificar aqui.
Os restantes canais, $Cb$ e $Cr$, são canais de crominância, que representam as diferenças dos canais azul e vermelho da luminância, respetivamente. Como o olho humano é menos sensível a estas componentes, podemos reduzir o número de amostras - downsampling - sem alterar a perceção da imagem reconstruída de forma significativa.
colormodels(barn)
Como apresentado acima, os canais de crominância podem ser resampled com menor detalhe, pois a uma distância de visualização normal, não existem perdas percetíveis de qualidade.
O codec JPEG permite rácios típicos de subsampling de 4:4:4 (sem subsampling), 4:2:2 , e 4:2:0. O rácio 4:2:2 reduz a resolução horizontal em ambos os canais Cb e Cr para metade, enquanto que o rácio 4:2:0 reduz a resolução horizontal e vertical para metade. Intuitivamente, podemos concluir que 4:2:0 resulta numa maior taxa de compressão ao custo de uma maior destrutividade, relativamente ao rácio 4:2:2.
De facto, as taxas de compressões relativas ao rácio 4:4:4 são:
DCT(barn, ratio=(4,2,0))
TODO Discuta os resultados obtidos em termos de potencial de compressão
DCT(barn, ratio=(4,2,0), block=8)
Compare os resultados obtidos com os resultados de 7.1.2 e discuta-os em termos de potencial de compressão.
DCT(barn, ratio=(4,2,0), block=64)
TODO Compare com os resultados anteriores e tire conclusões.
Fator de qualidade: 100
quantization(barn, qf=100)
Fator de qualidade: 75
quantization(barn, qf=75)
Fator de qualidade: 50
quantization(barn, qf=50)
Fator de qualidade: 25
quantization(barn, qf=25)
Fator de qualidade: 10
quantization(barn, qf=10)
TODO Comparação dos diferentes resultados e discussão da potencialidade de compressão
TODO Compare os resultados obtidos com os resultados da alínea 7 e tire conclusões.
DPCM(barn, ratio=(4,2,0), qf=75)
A codificação DPCM aplicada é uma codificação diferencial básica sobre os coeficientes DC da DCT, em que o coeficiente $c_i$ é codificado como a diferença entre este e o anterior: $d_i = c_i - c_{i-1}$.
Em imagens com transições suaves, estes valores são semelhantes - existe uma correlação elevada entre coeficientes adjacentes - pelo que as diferenças serão pequenas. Esta propriedade permite um estreitamento da gama de valores e uma menor variância deste, o que abre as portas para métodos de compressão entrópica.
Acima, conseguimos ver que as zonas do céu ficam praticamente a negro, e existe uma redução notável, ainda que menor, de coeficientes no centro das imagens.
verboseMetrics(barn, qf=100, ratio=(4,2,0))
MSE: 20.550 RMSE: 4.533 SNR: 34.058 dB PSNR: 35.003 dB
verboseMetrics(barn, qf=75, ratio=(4,2,0))
MSE: 171.586 RMSE: 13.099 SNR: 24.841 dB PSNR: 25.786 dB
verboseMetrics(barn, qf=50, ratio=(4,2,0))
MSE: 282.302 RMSE: 16.802 SNR: 22.679 dB PSNR: 23.624 dB
verboseMetrics(barn, qf=25, ratio=(4,2,0))
MSE: 422.080 RMSE: 20.545 SNR: 20.932 dB PSNR: 21.877 dB
verboseMetrics(barn, qf=10, ratio=(4,2,0))
MSE: 740.352 RMSE: 27.209 SNR: 18.492 dB PSNR: 19.436 dB
verboseMetrics(peppers, qf=100, ratio=(4,2,0))
MSE: 12.649 RMSE: 3.557 SNR: 33.905 dB PSNR: 37.110 dB
verboseMetrics(peppers, qf=75, ratio=(4,2,0))
MSE: 70.840 RMSE: 8.417 SNR: 26.423 dB PSNR: 29.628 dB
verboseMetrics(peppers, qf=50, ratio=(4,2,0))
MSE: 106.063 RMSE: 10.299 SNR: 24.670 dB PSNR: 27.875 dB
verboseMetrics(peppers, qf=25, ratio=(4,2,0))
MSE: 162.495 RMSE: 12.747 SNR: 22.818 dB PSNR: 26.022 dB
verboseMetrics(peppers, qf=10, ratio=(4,2,0))
MSE: 341.954 RMSE: 18.492 SNR: 19.586 dB PSNR: 22.791 dB
verboseMetrics(logo, qf=100, ratio=(4,2,0))
MSE: 9.283 RMSE: 3.047 SNR: 41.655 dB PSNR: 38.454 dB
verboseMetrics(logo, qf=75, ratio=(4,2,0))
MSE: 33.079 RMSE: 5.751 SNR: 36.137 dB PSNR: 32.935 dB
verboseMetrics(logo, qf=50, ratio=(4,2,0))
MSE: 55.404 RMSE: 7.443 SNR: 33.897 dB PSNR: 30.695 dB
verboseMetrics(logo, qf=25, ratio=(4,2,0))
MSE: 84.155 RMSE: 9.174 SNR: 32.081 dB PSNR: 28.880 dB
verboseMetrics(logo, qf=10, ratio=(4,2,0))
MSE: 182.662 RMSE: 13.515 SNR: 28.716 dB PSNR: 25.514 dB